﻿using System;
using System.Collections.Generic;
using System.Drawing;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using FlexCell;
using YArchitech.Controls;
using YJKRGeometry;
using TableTools;
using TableTools.Designer;

namespace HyCommonTableTool
{
	internal class TableSplitManager
	{
		public TableSplitManager(ExternalCommandData cmdData)
		{
			this.m_cmdData = cmdData;
			this.m_uidoc = cmdData.Application.ActiveUIDocument;
			this.GetXYDpi(ref this.m_dpiX, ref this.m_dpiY);
		}

		private void GetXYDpi(ref double Xdpi, ref double Ydpi)
		{
			using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
			{
				Xdpi = (double)graphics.DpiX;
				Ydpi = (double)graphics.DpiY;
			}
		}

		public bool ReadAndHandTableData()
		{
			FilterGroup filterGroup = new FilterGroup();
			Transaction transaction = new Transaction(this.m_uidoc.Document, "modify Scale");
			try
			{
				int scale = this.m_uidoc.ActiveView.Scale;
				Reference reference = this.m_uidoc.Selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, filterGroup, "请选择一个表格");
				Group group = this.m_uidoc.Document.GetElement(reference) as Group;
				if (group != null)
				{
					if (TableInterface.GridDrawView(this.m_cmdData, "表格工具") == ViewSelectResult.VSR_Cancel)
					{
						return false;
					}
					transaction.Start();
					this.m_uidoc.ActiveView.Scale = scale;
					transaction.Commit();
					if ((int)this.ReadTableData(group) == -1)
					{
						YJKMessageBox.Show("获取表格数据失败");
						return false;
					}
					this.HandleTableData();
				}
			}
			catch
			{
				if (transaction.IsValidObject && transaction.HasStarted())
				{
					transaction.RollBack();
				}
				return false;
			}
			return true;
		}

		private Result ReadTableData(Group groupGrid)
		{
			XYZ xyz = new XYZ();
			GridExtendedData.ReadGridExtendedData(ref xyz, groupGrid, ref this.m_gridRows, ref this.m_GridCols, ref this.m_cellExtendedInfo, ref this.dataRrefresh);
			if (this.m_gridRows.Count <= 0 || this.m_GridCols.Count <= 0 || this.m_cellExtendedInfo.Count <= 0)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private bool InterceptTable()
		{
			TableSplitJig tableSplitJig = new TableSplitJig(this.m_uidoc);
			if (tableSplitJig.DrawJigCurveRect(this.m_uidoc.ActiveView.RightDirection, "请选择表格插入点：", "请确定表格生成范围："))
			{
				double num = (double)this.m_uidoc.ActiveView.Scale / 100.0;
				XYZ xyz = new XYZ(tableSplitJig.EndPoint.X, tableSplitJig.StartPoint.Y, tableSplitJig.StartPoint.Z);
				this.m_dTableHigh = xyz.DistanceTo(tableSplitJig.EndPoint);
				this.m_dTableHigh /= num;
				if (Geometry.GreaterThan(tableSplitJig.StartPoint.Y, tableSplitJig.EndPoint.Y))
				{
					this.m_pt = tableSplitJig.StartPoint;
				}
				else
				{
					this.m_pt = tableSplitJig.EndPoint;
				}
				tableSplitJig.Dispose();
				return true;
			}
			return false;
		}

		private void HandleTableData()
		{
			int headRows = this.dataRrefresh.GridSetInfo.HeadRows;
			double dHeadHigh = 0.0;
			List<CellExtendedData> lstHeadDatas = new List<CellExtendedData>();
			int nNoHeadS;
			if (headRows != 0)
			{
				dHeadHigh = this.GetHeadHigh(headRows);
				if (!this.dataRrefresh.GridSetInfo.TitleDown)
				{
					int num = 1;
					nNoHeadS = num + headRows;
					lstHeadDatas = this.ExtractData(num, headRows);
				}
				else
				{
					int count = this.m_cellExtendedInfo.Count;
					int lastRow = this.m_cellExtendedInfo[count - 1].LastRow;
					int num = lastRow - headRows + 1;
					nNoHeadS = 1;
					lstHeadDatas = this.ExtractData(num, lastRow);
				}
			}
			else
			{
				nNoHeadS = 1;
			}
			this.SplitTable(lstHeadDatas, nNoHeadS, dHeadHigh);
		}

		private List<CellExtendedData> ExtractData(int nStartRow, int nLastRow)
		{
			List<CellExtendedData> list = new List<CellExtendedData>();
			foreach (CellExtendedData cellExtendedData in this.m_cellExtendedInfo)
			{
				if (cellExtendedData.FirstRow != cellExtendedData.LastRow || cellExtendedData.FirstCol != cellExtendedData.LastCol)
				{
					if (this.HandleMargeCell(cellExtendedData, nStartRow, nLastRow))
					{
						CellExtendedData cellExtendedData2 = new CellExtendedData(cellExtendedData.FirstRow, cellExtendedData.FirstCol, cellExtendedData.LastRow, cellExtendedData.LastCol, cellExtendedData.Id, cellExtendedData.BorderStyle);
						if (cellExtendedData.FirstRow < nStartRow)
						{
							cellExtendedData2.FirstRow = nStartRow;
						}
						if (cellExtendedData.LastRow > nLastRow)
						{
							cellExtendedData2.LastRow = nLastRow;
						}
						list.Add(cellExtendedData2);
					}
				}
				else if (cellExtendedData.FirstRow >= nStartRow && cellExtendedData.FirstRow <= nLastRow)
				{
					list.Add(cellExtendedData);
				}
			}
			return list;
		}

		private bool HandleMargeCell(CellExtendedData cell, int nStartRow, int nLastRow)
		{
			return (nStartRow <= cell.FirstRow && nLastRow >= cell.LastRow) || (nStartRow <= cell.FirstRow && nLastRow >= cell.FirstRow) || (nStartRow > cell.FirstRow && nLastRow < cell.LastRow) || (nStartRow <= cell.LastRow && nLastRow >= cell.LastRow);
		}

		private double GetHeadHigh(int nHeadRows)
		{
			double num = 0.0;
			if (!this.dataRrefresh.GridSetInfo.TitleDown)
			{
				for (int i = 0; i < nHeadRows; i++)
				{
					num += this.UnitTransform(this.m_gridRows[i]) * 100.0;
				}
			}
			else
			{
				for (int j = this.m_gridRows.Count - nHeadRows; j < this.m_gridRows.Count; j++)
				{
					num += this.UnitTransform(this.m_gridRows[j]) * 100.0;
				}
			}
			return num;
		}

		private void SplitTable(List<CellExtendedData> m_lstHeadDatas, int nNoHeadS, double dHeadHigh)
		{
			try
			{
				for (;;)
				{
					List<CellExtendedData> list = new List<CellExtendedData>();
					foreach (CellExtendedData item in m_lstHeadDatas)
					{
						list.Add(item);
					}
					if (!this.InterceptTable())
					{
						goto IL_298;
					}
					List<CellExtendedData> list2 = new List<CellExtendedData>();
					int num = 0;
                    FlexCell.Grid grid = new FlexCell.Grid();
					this.gridDraw = new GridToolExportImportRevit(this.m_cmdData, this.m_pt);
					this.gridDraw.m_bIsSplitTable = true;
					if (this.dataRrefresh.GridSetInfo.HeadRows != 0)
					{
						if (!this.dataRrefresh.GridSetInfo.TitleDown)
						{
							num = this.GetTableSplitRang_HandToUpOrNo(nNoHeadS, dHeadHigh);
							if (num < nNoHeadS)
							{
								YJKMessageBox.Show("选择区域较小");
								continue;
							}
							list2 = this.ExtractData(nNoHeadS, num);
							foreach (CellExtendedData item2 in list2)
							{
								list.Add(item2);
							}
							this.gridDraw.AbstractGridFromRevit(ref grid, this.m_gridRows, this.m_GridCols, list);
							this.DeleteBlank_HeadToUp(ref grid, nNoHeadS, num);
						}
						else
						{
							num = this.GetTableSplitRang_HandToDown(nNoHeadS, dHeadHigh);
							if (num < nNoHeadS)
							{
								YJKMessageBox.Show("选择区域较小");
								continue;
							}
							list2 = this.ExtractData(nNoHeadS, num);
							foreach (CellExtendedData item3 in list2)
							{
								list.Add(item3);
							}
							this.gridDraw.AbstractGridFromRevit(ref grid, this.m_gridRows, this.m_GridCols, list);
							this.DeleteBlank_HeadDown(ref grid, nNoHeadS, num);
						}
					}
					else
					{
						num = this.GetTableSplitRang_HandToUpOrNo(nNoHeadS, dHeadHigh);
						if (num < nNoHeadS)
						{
							YJKMessageBox.Show("选择区域较小");
							continue;
						}
						list2 = this.ExtractData(nNoHeadS, num);
						this.gridDraw.AbstractGridFromRevit(ref grid, this.m_gridRows, this.m_GridCols, list2);
						this.DeleteBlank_NoHead(ref grid, nNoHeadS, num);
					}
					for (int i = 1; i < grid.Rows; i++)
					{
						for (int j = 1; j < grid.Cols; j++)
						{
							Cell cell = grid.Cell(i, j);
							if (cell.Alignment != AlignmentEnum.LeftTop)
							{
								cell.Alignment = AlignmentEnum.CenterCenter;
							}
							cell.WrapText = true;
						}
					}
					if (this.gridDraw.SetGrid(this.m_cmdData, grid, CREATENEWVIEW.NONE))
					{
						this.gridDraw.SetRefreshData(this.dataRrefresh);
						this.gridDraw.DrawInRevitView();
					}
					if (this.m_bIsSplitEnd)
					{
						break;
					}
					nNoHeadS = num + 1;
				}
				YJKMessageBox.Show("表格拆分完成");
				IL_298:;
			}
			catch (Exception)
			{
				YJKMessageBox.Show("数据获取失败");
			}
		}

		private int GetTableSplitRang_HandToUpOrNo(int nSplitRow, double dHeadHigh)
		{
			for (int i = nSplitRow - 1; i < this.m_gridRows.Count; i++)
			{
				double num = this.UnitTransform(this.m_gridRows[i]) * 100.0;
				dHeadHigh += num;
				if (Geometry.LessThan(this.m_dTableHigh, dHeadHigh, 0.001))
				{
					return i;
				}
			}
			this.m_bIsSplitEnd = true;
			return this.m_gridRows.Count;
		}

		private int GetTableSplitRang_HandToDown(int nSplitRow, double dHeadHigh)
		{
			int headRows = this.dataRrefresh.GridSetInfo.HeadRows;
			for (int i = nSplitRow - 1; i < this.m_gridRows.Count - headRows; i++)
			{
				double num = this.UnitTransform(this.m_gridRows[i]) * 100.0;
				dHeadHigh += num;
				if (Geometry.LessThan(this.m_dTableHigh, dHeadHigh, 0.001))
				{
					return i;
				}
			}
			this.m_bIsSplitEnd = true;
			return this.m_gridRows.Count - headRows;
		}

		private void DeleteBlank_HeadToUp(ref FlexCell.Grid grid, int nDelStart, int nDelLast)
		{
			int num = this.dataRrefresh.GridSetInfo.HeadRows + 1;
			if (grid.Rows - 1 != nDelLast)
			{
				grid.Range(nDelLast + 1, 1, grid.Rows - 1, grid.Cols - 1).DeleteByRow();
			}
			if (num != nDelStart)
			{
				grid.Range(num, 1, nDelStart - 1, grid.Cols - 1).DeleteByRow();
			}
		}

        private void DeleteBlank_HeadDown(ref FlexCell.Grid grid, int nDelStart, int nDelLast)
		{
			int num = grid.Rows - this.dataRrefresh.GridSetInfo.HeadRows;
			if (nDelLast + 1 != num)
			{
				grid.Range(nDelLast + 1, 1, num - 1, grid.Cols - 1).DeleteByRow();
			}
			if (nDelStart != 1)
			{
				grid.Range(1, 1, nDelStart - 1, grid.Cols - 1).DeleteByRow();
			}
		}

        private void DeleteBlank_NoHead(ref FlexCell.Grid grid, int nDelStart, int nDelLast)
		{
			if (nDelLast != grid.Rows - 1)
			{
				grid.Range(nDelLast + 1, 1, grid.Rows - 1, grid.Cols - 1).DeleteByRow();
			}
			if (nDelStart != 1)
			{
				grid.Range(1, 1, nDelStart - 1, grid.Cols - 1).DeleteByRow();
			}
		}

		private double UnitTransform(short value)
		{
			return (double)value / this.m_dpiY * 0.08333;
		}

		private ExternalCommandData m_cmdData;

		private UIDocument m_uidoc;

		private double m_dTableHigh;

		public XYZ m_pt;

		private List<short> m_gridRows = new List<short>();

		private List<short> m_GridCols = new List<short>();

		private List<CellExtendedData> m_cellExtendedInfo = new List<CellExtendedData>();

		private bool m_bIsSplitEnd;

		private GridDataRefresh dataRrefresh = new GridDataRefresh();

		private GridToolExportImportRevit gridDraw;

		private double m_dpiY;

		private double m_dpiX;
	}
}
